package xyz.thoughtset.viewer.ai.mcp.client.entity;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.spec.McpSchema;

import java.io.Closeable;
import java.util.List;
import java.util.function.BiPredicate;


public record McpClientLink(McpBotInfo mcpBotInfo,
                            McpSyncClient mcpSyncClient,
                            McpSchema.InitializeResult initializeResult) implements Closeable {

    public static Builder builder() {
        return new Builder();
    }

    public List<McpSchema.Tool> mcpTools() {
        return mcpSyncClient.listTools().tools();
    }
    public String clientName(){
        return mcpSyncClient.getClientInfo().name();
    }

    public BiPredicate<McpBotInfo, McpSchema.Tool> defaultToolFilter() {
        return (client, tool) -> {
            if (mcpBotInfo.getDisableToolNames() == null || mcpBotInfo.getDisableToolNames().isEmpty()) {
                return true;
            }
            String[] disableToolArr = mcpBotInfo.getDisableToolNames().split(",");
            for (String ele : disableToolArr) {
                if (ele.trim().equalsIgnoreCase(tool.name())) {
                    return false;
                }
            }
            return true;
        };
    }

    @Override
    public void close() {
        mcpSyncClient.close();
    }

    public static final class Builder {


        private McpBotInfo clientInfo;
        private McpClient.SyncSpec spec;

        private Builder() {
        }

        public McpClientLink.Builder spec(McpClient.SyncSpec spec) {
            this.spec = spec;
            return this;
        }

        public McpClientLink.Builder clientInfo(McpBotInfo clientInfo) {
            this.clientInfo = clientInfo;
            return this;
        }

        public McpClientLink build() {
            if (this.spec == null) {
                if (this.clientInfo == null){
                    throw new IllegalStateException("McpBotInfo is required");
                }
            }
            McpSyncClient mcpSyncClient = this.spec.build();
            McpSchema.InitializeResult initializeResult = mcpSyncClient.initialize();
            return new McpClientLink(clientInfo,mcpSyncClient, initializeResult);
        }

    }


}
